home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
telecomm
/
zmdm.zoo
/
expandar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-27
|
15KB
|
734 lines
/*
* Examine each argument given to expandargs()
* If it is a directory, then expand it
* to all its component files, recursively
* till you bottom out.
* If it is not a directory, then just pass it on.
*
* Inputs: routine, argc, argv
* Outputs: nargc, nargv (calls routine(nargc, nargv))
* To test: compile with -DTEST
* define MWC if using Mark Williams C
* run with a directory as an arg
* Author: JRB bammi@mandrill.ces.CWRU.edu
* Requirements: Mark Williams C or Alcyon C
* Wants lots of Dynamic memory. It
* all depends upon how many files you
* have. Use the -P option to prune
* out subdirectories and do things
* one at a time, if you keep running
* out of memory.
* With Mark Williams i use _stksize = 128K
* With Alcyon i use memory model 2 (half of
* of avail memory) in GEMSTART.S
*
* WARNINGS: Be CAREFUL about the 40 folder bug. Use
* GEMBOOT or FOLDRXXX when dealing with
* a deeply nested file structure.
*
* Added -P name prune option at the suggestion of dietz@zhmti
* Multiple -P's may be given on the command line.
* -P name may be given anywhere on the command line. -P name
* will prune the subdirectories named as arguement to -P.
* ie: when the program is decending the file hierarchy it
* will not visit the pruned branches.
* NOTE that the option is -P and not -p
* (-p is a valid sz option).
* NOTE that the arguement given to -P can be the name
* of a file or a directory. In case it is a file,
* that file is skipped.
*
*/
/*
* Expand argc, so that the called routine(nargc,nargv) receives only
* filenames, in nargv[][]
*
************************************************************************
* *
* WARNING: Be CAREFUL about the 40 folder bug. Use *
* GEMBOOT or FOLDRXXX when dealing with *
* a deeply nested file structure. *
* *
************************************************************************
*
* Jwahar Bammi
* bang: {any internet host}!dsrgsun.ces.CWRU.edu!bammi
* domain: bammi@dsrgsun.ces.CWRU.edu
* GEnie: J.Bammi
*/
#ifdef TEST
#include <stdio.h>
#include <osbind.h>
#include <ctype.h>
#endif
#ifdef TRUE
#undef TRUE
#endif
#ifdef OK
#undef OK
#endif
#ifdef FALSE
#undef FALSE
#endif
#define TRUE 1
#define OK 0
#define FALSE 0
#define Realloc realloc
#ifdef TEST
struct stat
{
char st_sp1[21]; /* Junk */
char st_mode; /* File attributes */
int st_time; /* Mod Time */
int st_date; /* Mod date */
long st_size; /* File size */
char st_name[14]; /* File name */
};
#endif
typedef struct _prunelist {
char *name; /* name of subdirectory to prune */
struct _prunelist *next; /* ptr to next */
} PRUNELIST;
static char *ProgName;
static PRUNELIST *PruneList = (PRUNELIST *)NULL; /* Head of PruneList */
#if defined(__STDC__) || defined(__cplusplus)
# define P_(s) s
#else
# define P_(s) ()
#endif
static char **CopyToNargv P_((char *string, int nargc, char **nargv));
static char **ExpandStack P_((char **Stack));
static void FreeStack P_((void));
static void FreeNargv P_((int nargc, char *nargv[]));
static void FreePrune P_((void));
static void FreeUp P_((int nargc, char **nargv));
static int PushDir P_((char *name));
static char *PopDir P_((void));
static int ProcessDirs P_((int *nargc, char ***nargv));
static PRUNELIST *AddPrune P_((PRUNELIST *list, char *name));
static int OnPruneList P_((PRUNELIST *list, char *name));
static int isdir P_((char *name, int attr));
char *alltolower P_((char *s));
#undef P_
extern int existd();
expandargs(routine, argc, argv)
int (*routine)();
int argc;
char **argv;
{
register int status;
int nargc;
char **nargv;
extern char **CopyToNargv();
extern PRUNELIST *AddPrune();
extern int existd();
nargc = 0;
nargv = (char **)NULL;
ProgName = *argv;
/* copy argv[0] blindly */
if((nargv = CopyToNargv(*argv, nargc, nargv)) == (char **)NULL)
{
FreeUp(nargc, nargv);
return(~OK);
}
nargc++;
while((--argc) > 0)
{
argv++;
if(**argv == '-')
{
/* copy any options except -P */
#ifdef TEST
/* some shell pass -P as -p */
if( ((*argv)[1] == 'P') || ((*argv)[1] == 'p'))
#else
if( (*argv)[1] == 'P')
#endif
{
if((--argc) <= 0)
{
fprintf(STDERR,"no argument given to -P\n");
FreeUp(nargc, nargv);
return(~OK);
}
if((PruneList = AddPrune(PruneList,*++argv))
== (PRUNELIST *)NULL)
{
FreeUp(nargc, nargv);
return(~OK);
}
}
else
{
if((nargv = CopyToNargv(*argv, nargc, nargv))
== (char **)NULL)
{
FreeUp(nargc, nargv);
return(~OK);
}
else
nargc++;
}
}
else
{
/* If its not on the PruneList then */
if(!OnPruneList(PruneList, *argv))
{
/* if it is a directory, push it */
if(existd(*argv))
{
if((status = PushDir(*argv)) != OK)
{
FreeUp(nargc, nargv);
return(status);
}
}
else
{
/* it is NOT a directory, copy to nargv */
if((nargv = CopyToNargv(*argv, nargc, nargv))
== (char **)NULL)
{
FreeUp(nargc, nargv);
return(~OK);
}
else
nargc++;
}
}
}
} /* while */
/* process pushed directories if any */
if((status = ProcessDirs(&nargc, &nargv)) != OK)
{
FreeUp(nargc, nargv);
return(status);
}
/* else Free the Stack and Prune List, call *routine */
FreeStack();
FreePrune();
status = (*routine)(nargc, nargv);
FreeNargv(nargc, nargv);
return status;
}
/*
* Expand nargv by an element and copy a String into the new element
*
*/
static char **CopyToNargv(string, nargc, nargv)
char *string;
int nargc;
char **nargv;
{
#ifdef __GNUC__
extern void *malloc(size_t), *Realloc(void *, size_t);
#else
extern char *malloc(), *Realloc();
#endif
extern char *strcpy();
#ifdef __GNUC__
extern size_t strlen();
#else
extern int strlen();
#endif
/* expand nargv by 1 element */
if(nargv == (char **)NULL)
/* do it with malloc for the first one */
nargv = (char **)malloc(sizeof(char **));
else
/* do it with Realloc for others */
nargv = (char **)Realloc(nargv, (nargc+1)*sizeof(char **));
if(nargv == (char **)NULL)
{
/* failed to get memory */
fprintf(STDERR,"%s(CopyToNargv()): Out of Memory\n", ProgName);
return ((char **)NULL);
}
/* Get mem for string */
if(( nargv[nargc] = malloc(strlen(string)+1)) == (char *)NULL)
{
/* failed to get memory */
fprintf(STDERR,"%s(CopyToNargv()): Out of Memory\n", ProgName);
return ((char **)NULL);
}
/* copy string into nargv[nargc] */
(void)strcpy( nargv[nargc], string);
return(nargv);
}
static char **Stack = (char **)NULL; /* directory stack */
static char StackSize = 0; /* Size of current Stack */
static int Top = -1;
#define STACK_EMPTY (Top < 0)
#define CHUNKSIZE 16
/*
* Grow the Stack by one chunk of CHUNKSIZE elements
*
*/
static char **ExpandStack(Stack)
char **Stack;
{
#ifdef __GNUC__
extern void *malloc(size_t), *Realloc(void *, size_t);
#else
extern char *malloc(), *Realloc();
#endif
/* Grow Stack */
if(Stack == (char **)NULL)
/* with malloc */
Stack = (char **)malloc(CHUNKSIZE * sizeof(char **));
else
/* with Realloc */
Stack = (char **)Realloc(Stack, (StackSize+CHUNKSIZE) *
sizeof(char **));
if(Stack == (char **)NULL)
{
/* outa mem */
fprintf(STDERR,"%s(ExpandStack()): Out of Memory\n", ProgName);
return((char **)NULL);
}
StackSize += CHUNKSIZE;
return(Stack);
}
/*
* Free the Stack
*
*/
static void FreeStack()
{
if(StackSize > 0)
(void)free(Stack);
Stack = (char **)NULL;
StackSize = 0;
Top = -1;
}
/*
* Free Nargv
*
*/
static void FreeNargv(nargc, nargv)
int nargc;
char *nargv[];
{
register int i;
for(i = 0; i < nargc; i++)
(void)free(nargv[i]);
if(nargc > 0)
(void)free(nargv);
}
/*
* Free the PruneList
*
*/
static void FreePrune()
{
register PRUNELIST *p, *next;
for(p = PruneList; p != (PRUNELIST *)NULL; p = next)
{
next = p->next;
(void)free(p);
}
PruneList = (PRUNELIST *)NULL;